﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Allan.Cards
{
    /// <summary>
    /// Provides a base class for a card game
    /// </summary>
    public abstract class Game
    {
        public List<Player> Players { get; protected set; }

        protected Deck deck;
        protected Random randSrc;

        public CardCollection Table;

        public event GameEventHandler PlayerAdded;
        public event GameEventHandler TurnChanged;
        public event GameEventHandler GameOver;
        public event GameEventHandler InitialDealDone;

        public bool Started { get; protected set; }

        protected int playerTurn;

        public Player ActivePlayer
        {
            get
            {
                return Players[playerTurn];
            }
        }

        public virtual void AddPlayer(Player p)
        {
            if (Started) throw (new ApplicationException("Game already in progress"));
            Players.Add(p);
            if (PlayerAdded != null) PlayerAdded(this, p);
        }


        protected virtual void InitialDeal()
        {
            
            Table = new CardCollection();
            deck = new Deck(0);
            deck.Shuffle();

        }

        /// <summary>
        /// Returns true when the game is over
        /// </summary>
        /// <returns></returns>
        protected virtual bool CheckGameOver()
        {
            return false;
        }

        /// <summary>
        /// 
        /// </summary>
        protected virtual void PlayerTurns()
        {
            playerTurn = randSrc.Next(0, Players.Count);
            while (!CheckGameOver())
            {
                if (TurnChanged != null) TurnChanged(this, this.ActivePlayer);
                Players[playerTurn].PlayerTurn(this);
                playerTurn++;
                if (playerTurn >= Players.Count) playerTurn = 0;
            }
        }

        public virtual void StartGame()
        {
            if (Started) throw (new ApplicationException("Game already in progress"));
            else Started = true;
            foreach (Player p in Players) p.PlayerNewGameInit(this);
            InitialDeal();
            if (InitialDealDone != null) InitialDealDone(this, null);
            
            PlayerTurns();

            if (GameOver != null) GameOver(this, null);
        }

        public Game()
        {
            randSrc = new Random();
            Players = new List<Player>();
        }
    }
}
